6359
2272
Comp.lang.c ++ üzerinde C ++ / STL'nin Gizli Özellikleri ve Karanlık Köşelerini okuduktan sonra, aşağıdaki kod parçacığının hem Visual Studio 2008 hem de G ++ 4.4'te derlenip çalışmasına şaşırdım.
İşte kod:
#include 
int main ()
{
int x = 10;
while (x -> 0) // x 0'a gider
{
printf ("% d", x);
}
}
Çıktı:
9 8 7 6 5 4 3 2 1 0
GCC'de de çalıştığı için bunun C olduğunu varsayıyorum. Bu standartta nerede tanımlanmıştır ve nereden gelmiştir? 
-> bir operatör değildir. Aslında iki ayrı operatördür - ve>.
Koşulun kodu, x'in orijinal (azaltılmamış) değerini döndürürken x'i azaltır ve ardından orijinal değeri> operatörünü kullanarak 0 ile karşılaştırır.
Daha iyi anlamak için ifade şu şekilde yazılabilir:
süre ((x--)> 0)
|
Veya tamamen farklı bir şey için ... x, 0'a kayar.
süre (x - \
\
\
\
> 0)
printf ("% d", x);
O kadar matematiksel değil, ama ... her resim bin kelimeyi boyar ...
|
Bu çok karmaşık bir operatör, bu nedenle ISO / IEC JTC1 (Ortak Teknik Komite 1) bile açıklamasını C ++ Standardının iki farklı bölümüne yerleştirdi.
Şaka bir yana, bunlar iki farklı operatördür: - ve> sırasıyla C ++ 03 Standardının §5.2.6 / 2 ve §5.9'da açıklanmıştır.
|
Eşdeğeri
süre (x--> 0)
x-- (azaltma sonrası) x = x-1'e eşdeğerdir, bu nedenle kod şu şekle dönüşür:
while (x> 0) {
x = x-1;
// mantık
}
x--; // x <= 0 olduğunda gönderi eksiltme yapılır
|
x ters yönde sıfıra daha da hızlı gidebilir:
int x = 10;
süre (0 <---- x)
{
printf ("% d", x);
}
8 6 4 2
Hızı bir okla kontrol edebilirsiniz!
int x = 100;
while (0 <-------------------- x)
{
printf ("% d", x);
}
90 80 70 60 50 40 30 20 10
;)
|
Onun
#include 
int main (void) {
int x = 10;
while (x--> 0) {// x 0'a gider
printf ("% d", x);
}
dönüş 0;
}
Sadece boşluk her şeyi komik gösterir - eksiltmeler ve> karşılaştırmalar.
|
-> kullanımının tarihsel önemi vardır. Azaltma, x86 mimarisinde artıştan daha hızlıydı (ve bazı durumlarda hala öyle). -> kullanılması, x'in 0'a gideceğini önerir ve matematiksel geçmişi olanlara hitap eder.
|
süre (x--> 0)
bu nasıl ayrıştırılır.
|
Tamamen inek, ama bunu kullanacağım:
# tanımla; while
int main (int argc, char * argv [])
{
int n = atoi (argv [1]);
do printf ("n,% d \ n", n) as (n -> 0);
dönüş 0;
}
|
Okuduğum bir kitap (hangi kitabı doğru hatırlamıyorum) şunu söylüyordu: Derleyiciler sol sağ kuralı kullanarak ifadeleri en büyük simgeye göre çözümlemeye çalışıyorlar.
Bu durumda ifade:
x -> 0
En büyük jetonlara ayrıştırılır:
simge 1: x
simge 2: -
simge 3:>
simge 4: 0
sonuç: x--> 0
Aynı kural bu ifade için de geçerlidir:
a ----- b
Ayrıştırdıktan sonra:
simge 1: a
simge 2: -
simge 3: -
simge 4: -
simge 5: b
sonuç: (a -) - - b
Umarım bu, karmaşık ifadeyi anlamaya yardımcı olur ^^
|
Bu tamamen aynı
süre (x--)
{
printf ("% d", x);
}
negatif olmayan sayılar için
|
Her neyse, artık bir "gider" operatörümüz var. "->" bir yön olarak hatırlanması kolaydır ve "x sıfıra giderken" anlamı-düzdür.
Ayrıca, bazı platformlarda "for (x = 10; x> 0; x -)" den biraz daha etkilidir.
|
Bu kod önce x ve 0'ı karşılaştırır ve sonra x'i azaltır. (İlk yanıtta ayrıca şunu da belirtiyor: x'i sonradan azaltıyorsunuz ve sonra x ve 0'ı> operatörüyle karşılaştırıyorsunuz.) Bu kodun çıktısına bakın:
9 8 7 6 5 4 3 2 1 0
Şimdi çıktıda 0 görerek önce karşılaştırıp sonra azaltıyoruz.
Önce düşürmek ve sonra karşılaştırmak istiyorsak, bu kodu kullanın:
#include 
int main (void)
{
int x = 10;
while (--x> 0) // x 0'a gider
{
printf ("% d", x);
}
dönüş 0;
}
Bu çıktı:
9 8 7 6 5 4 3 2 1
|
Bu kodu çalıştırdığımda derleyicim 9876543210'u yazdıracak.
#include 
int main ()
{
int x = 10;
while (x -> 0) // x 0'a gider
{
std :: cout << x;
}
}
Beklenildiği gibi. While (x--> 0) aslında while (x> 0) anlamına gelir. X-- postu x'i azaltır.
süre (x> 0)
{
x--;
std :: cout << x;
}
aynı şeyi yazmanın farklı bir yoludur.
Yine de orijinalin "x 0'a giderken" gibi görünmesi güzel.
|
- ve> arasında eksik boşluk var. x sonradan azaltılır, yani x> 0? koşulu kontrol edildikten sonra azaltılır.
|
- eksiltme operatörü ve> büyüktür operatörüdür.
İki operatör -> gibi tek bir operatör olarak uygulanır.
|
İki operatörün birleşimidir. Birincisi - değeri azaltmak içindir ve> değerin sağdaki işlenenden büyük olup olmadığını kontrol etmek içindir.
#include 
int main ()
{
int x = 10;
süre (x--> 0)
printf ("% d", x);
dönüş 0;
}
Çıktı şu şekilde olacaktır:
9 8 7 6 5 4 3 2 1 0
|
Aslında, x eksilme işlemidir ve bu koşulla kontrol edilmektedir. Değil ->, (x--)> 0
Not: x'in değeri, eksilme sonrası olduğu için koşul kontrol edildikten sonra değiştirilir. Bazı benzer durumlar da ortaya çıkabilir, örneğin:
-> x -> 0
++> x ++> 0
-> = x -> = 0
++> = x ++> = 0
|
C ve C ++ "maksimum munch" kuralına uyar. Aynı şekilde a --- b, (a--) - b'ye çevrilir, sizin durumunuzda x -> 0 (x -)> 0'a çevrilir.
Kuralın esas olarak söylediği şey, soldan sağa doğru, geçerli bir ifade oluşturacak maksimum karakter sayısı alınarak ifadelerin oluşturulduğudur.
|
Neden bu kadar karışıklık?
Orijinal sorunun basit cevabı şudur:
#include 
int main ()
{
int x = 10;
while (x>0)
{
printf ("% d", x);
x = x-1;
}
}
Aynı şeyi yapıyor. Bunu böyle yapmalısın demiyorum ama aynı şeyi yapıyor ve soruyu tek bir gönderide cevaplamış olur.
X-- yukarıdakinin kısaltmasıdır ve> normalden büyükten büyük bir operatördür. Büyük bir gizem yok!
Günümüzde basit şeyleri karmaşık hale getiren çok fazla insan var;)
|
Geleneksel şekilde while döngüsü parantezinde () bir koşul ve küme parantezleri {} içinde bir sonlandırma koşulu tanımlardık, ancak -> her ikisini aynı anda tanımlar.
Örneğin:
int abc (geçersiz)
{
int a = 5
while ((a--)> 0) // İkisini birden azalt ve karşılaştır
{
// Kod
}
}
Bu, a'yı azaltır ve a, 0'dan büyükken döngüyü çalıştırır.
Geleneksel olarak şu şekilde olacaktır:
int abc (geçersiz)
{
int a = 5;
süre (a> 0)
{
a--;
// Kod
}
a--;
}
Her iki şekilde de aynı şeyi yapıyoruz ve aynı hedeflere ulaşıyoruz.
|
(x -> 0), (x--> 0) anlamına gelir.
(X ->) Çıkışını kullanabilirsiniz: 9 8 7 6 5 4 3 2 1 0
Kullanabilirsiniz (- x> 0) Bu ortalama (--x> 0) Çıktı: 9 8 7 6 5 4 3 2 1
Kullanabilirsiniz
(- \
\
x> 0)
Çıkış: 9 8 7 6 5 4 3 2 1
Kullanabilirsiniz
(\
\
x -> 0)
Çıkış: 9 8 7 6 5 4 3 2 1 0
Kullanabilirsiniz
(\
\
x -> 0
\
\
)
Çıkış: 9 8 7 6 5 4 3 2 1 0
Ayrıca kullanabilirsiniz
(
x
->
)
Çıkış: 9 8 7 6 5 4 3 2 1 0
Aynı şekilde, bu komutu başarıyla yürütmek için birçok yöntemi deneyebilirsiniz.
|
İşte - tekli sonradan eksiltme operatörü.
while (x--> 0) // x 0'a gider
{
printf ("% d", x);
}
Başlangıçta durum şu şekilde değerlendirilecektir:
(x> 0) // 10> 0
Şimdi koşul doğru olduğu için, azaltılmış bir değerle döngüye girecek
x-- // x = 9
Bu yüzden ilk basılan değer 9
Ve bunun gibi. Son döngüde x = 1, dolayısıyla koşul doğrudur. Tekli operatöre göre, değer yazdırma sırasında x = 0 olarak değiştirildi.
Şimdi, x = 0, koşulu (x> 0) yanlış olarak değerlendirir ve while döngüsü çıkar.
|
Bu -> hiç bir operatör değildir. -> gibi bir operatörümüz var ama -> gibi değil. Bu sadece while (x--> 0) 'ın yanlış bir yorumudur, bu da x'in son azaltma operatörüne sahip olduğu ve bu döngü sıfırdan büyük olana kadar çalışacağı anlamına gelir.
Bu kodu yazmanın başka bir basit yolu while (x--) olacaktır. While döngüsü yanlış bir koşul aldığında durur ve burada sadece bir durum vardır, yani 0. Yani x değeri sıfıra düştüğünde duracaktır.
|
Oldukça aktif soru. Bu soruyu cevaplamak için 10 itibar kazanın. İtibar koşulu, bu sorunun istenmeyen postalardan ve yanıtlanmayan etkinliklerden korunmasına yardımcı olur.
Aradığın cevap değil mi? C ++ c operatörleri kod formatlama standartlarına uygunluk etiketli diğer sorulara göz atın veya kendi sorunuzu sorun.